#ifndef M_TINYXMLREADER_H
#define M_TINYXMLREADER_H

#include "xmlreader.h"
#include "tinyxml.h"

namespace Engine
{
	/**
	*   Implementation of xml attributes with tinyxml.
	*/
	class TinyXmlAttribute : public XmlAttribute
	{
	public:
		TinyXmlAttribute(TiXmlAttribute* attr) : m_attribute(attr){}

		virtual RefPtr<XmlAttribute> Next()
		{
			TiXmlAttribute* attr = m_attribute->Next();
			if(attr != NULL)
				return RefPtr<XmlAttribute>(new TinyXmlAttribute(attr));
			else
				return RefPtr<XmlAttribute>();
		}
		virtual std::string Name()
		{
			return m_attribute->Name();
		}
		virtual std::string Value()
		{
			return m_attribute->Value();
		}
	private:
		TiXmlAttribute* m_attribute;
	};



	/**
	*   Implementation of xml elements with tinyxml.
	*/
	class TinyXmlElement : public XmlElement
	{
	public:
		TinyXmlElement(TiXmlElement* elem) : m_element(elem){}

		virtual RefPtr<XmlElement>   NextSiblingElement()
		{
			TiXmlElement* elem = m_element->NextSiblingElement();
			if( elem != NULL)
				return RefPtr<XmlElement>(new TinyXmlElement(elem));
			else
				return RefPtr<XmlElement>();
		}
		virtual RefPtr<XmlElement> FirstChildElement()
		{
			TiXmlElement* elem = m_element->FirstChildElement();
			if( elem != NULL)
				return RefPtr<XmlElement>(new TinyXmlElement(elem));
			else
				return RefPtr<XmlElement>();			
		}
		virtual RefPtr<XmlAttribute> FirstAttribute()
		{			
			TiXmlAttribute* attr = m_element->FirstAttribute();
			if(attr != NULL)
				return RefPtr<XmlAttribute>(new TinyXmlAttribute(attr));
			else
				return RefPtr<XmlAttribute>();
		}
		virtual std::string Value()
		{
			return m_element->Value();
		}
	private:
		TiXmlElement* m_element;
	};

	/**
	*   Implementation of xml document with tinyxml.
	*/
	class TinyXmlDocument : public XmlDocument
	{
	public:		

		~TinyXmlDocument(){}

		virtual bool Load(const std::string& fname)
		{
			return m_document.LoadFile(fname.c_str());
		}
		
		virtual bool Parse(const char* buf)
		{
			return m_document.Parse(buf) != NULL;
		}

		virtual RefPtr<XmlElement> FirstChildElement()
		{
			TiXmlElement* elem = m_document.FirstChildElement();
			if( elem != NULL)
				return RefPtr<XmlElement>(new TinyXmlElement(elem));
			else
				return RefPtr<XmlElement>();
		}
		
		virtual std::string ErrorDesc()
		{
			return m_document.ErrorDesc();
		}
	private:
		TiXmlDocument m_document;
	};
}

#endif
